using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Animatable : MonoBehaviour {

    public int spriteSheetXSize = 1;
    public int spriteSheetYSize = 1;

    private class Animation
    {
        public string name;
        public int y;
        public int startX;
        public int endX;
        public float secondsPerFrame;
    }
    private List<Animation> animations;
    private Animation currentAnimation;

    private float timeInCurrentAnimation;
    private bool looping;
    private bool reversed;

    public void InitializeAnimationList()
    {
        animations = new List<Animation>();
    }

    public void AddAnimation(string name, int y, int startX, int endX, float secondsPerFrame)
    {
        Animation a = new Animation();
        a.name = name;
        a.y = y;
        a.startX = startX;
        a.endX = endX;
        a.secondsPerFrame = secondsPerFrame;
        animations.Add(a);
    }
	
	// Update is called once per frame
    protected virtual void Update()
    {
        //Ugh, start inheritance woes..
        renderer.material.mainTextureScale = new Vector2(1.0f / spriteSheetXSize - .002f, 1.0f / spriteSheetYSize - .002f);

        if (currentAnimation!=null)
        {
            int frame = Mathf.FloorToInt(timeInCurrentAnimation / currentAnimation.secondsPerFrame);
            int numFrames = currentAnimation.endX - currentAnimation.startX + 1;

            if (looping)
            {
                if (frame > numFrames - 1)
                {
                    frame %= numFrames;
                }
            }

            if (frame > numFrames - 1)
            {
                OnAnimationFinished(currentAnimation.name);
                currentAnimation = null;
            }
            else
            {
                //Debug.Log(frame, this);
                if (reversed)
                    SetFrame(currentAnimation.endX - frame, currentAnimation.y);
                else
                    SetFrame(currentAnimation.startX + frame, currentAnimation.y);
            }
        }
        timeInCurrentAnimation += Time.deltaTime;
	}

    public void SetFrame(int x, int y)
    {
        renderer.material.mainTextureOffset = new Vector2(((float)x / spriteSheetXSize + .001f), (float)(spriteSheetYSize-y-1) / (spriteSheetYSize + .001f));
    }

    Animation GetAnimationByName(string name)
    {
        foreach (Animation a in animations)
        {
            if (a.name == name)
            {
                return a;
            }
        }
        Debug.Log("No animation named " + name, this);
        return null;
    }

    public string GetCurrentAnimationName()
    {
        if (currentAnimation!=null)
        {
            return currentAnimation.name;
        }
        else
        {
            return "";
        }
    }

    public void StartAnimation(string name, bool iLooping=false, bool iReversed = false)
    {
        currentAnimation = GetAnimationByName(name);
        timeInCurrentAnimation = 0.0f;
        looping = iLooping;
        reversed = iReversed;
    }

    protected virtual void OnAnimationFinished(string name)
    {
    }

}
